package org.ala.clickhouse.datasource;

import java.sql.Connection;
import java.sql.SQLException;
import java.util.Map;
import java.util.Properties;
import java.util.stream.Collectors;

import javax.sql.DataSource;

import org.ala.clickhouse.config.ClickHouseConfig;
import org.springframework.jdbc.datasource.lookup.AbstractRoutingDataSource;
import org.springframework.util.StringUtils;

import com.alibaba.druid.filter.FilterChainImpl;
import com.alibaba.druid.pool.DruidDataSource;
import com.clickhouse.jdbc.ClickHouseDataSource;
import com.clickhouse.jdbc.ClickHouseDriver;


/**
 *	动态路由数据源
 *
 *	@author ala
 *	@date 2025年6月7日
 */
@SuppressWarnings("deprecation")
public class ClickHouseRouterDataSource extends AbstractRoutingDataSource {

	
	/**
	 * 	默认的数据源
	 */
	protected DataSource defaultDataSource;
	/**
	 * 	数据源键值对
	 */
	protected Map<String, DataSource> dataSources;
	
	
	@Override
	public void afterPropertiesSet() {
		//	屏蔽掉父类的初始化
//		super.afterPropertiesSet();
	}
	
	@Override
	protected Object determineCurrentLookupKey() {
		return ClickHouseRouterDataSourceThreadLocal.get();
	}

	/**
	 * 	取数据源
	 */
	@Override
	protected DataSource determineTargetDataSource() {
		String key = (String) determineCurrentLookupKey();
		if (key == null || ClickHouseConfig.DEFAULT.equals(key)) {
			return defaultDataSource;
		} else {
			DataSource ds = dataSources.get(key);
			if (ds == null) {throw new RuntimeException(String.format("key无法找到CK数据源 key:%s", key));}
			return ds;
		}
	}

	/**
	 * 	根据配置信息初始化
	 * @throws SQLException 
	 */
	public void init(ClickHouseConfig config) throws SQLException {
		defaultDataSource = parseDataSource(config.getDef());
		
		dataSources = config.getInfos().entrySet().stream().collect(Collectors.toMap(e -> e.getKey(), e -> {
			try {
				return parseDataSource(e.getValue());
			} catch (SQLException e1) {
				throw new RuntimeException(e1);
			}
		}, (o,n) -> n));
	}
	/**
	 * 	根据配置项初始化数据源
	 * @throws SQLException 
	 */
	@SuppressWarnings({ "serial" })
	public DataSource parseDataSource(ClickHouseConfig.Info info) throws SQLException {
		//	ClickHouse的驱动类
//		Properties props = new Properties();
//		props.setProperty("user", info.getUsername());
//		props.setProperty("password", info.getPassword());
//		DataSourceImpl dsi = new DataSourceImpl(info.getUrl(), props);
//		Driver driver = new Driver(dsi);
		
		ClickHouseDataSource ds = new ClickHouseDataSource(info.getUrl());
		//	Druid数据源
		DruidDataSource druid = new DruidDataSource() {
		    public Connection createPhysicalConnection(String url, Properties info) throws SQLException {
		        Connection conn;
		        if (getProxyFilters().size() == 0) {
					if (StringUtils.isEmpty(username) || StringUtils.isEmpty(password)) {
						conn = ds.getConnection();
					} else {
						conn = ds.getConnection(username, password);
					}
		        } else {
		            conn = new FilterChainImpl(this).connection_connect(info);
		        }
		        createCount.incrementAndGet();
		        return conn;
		    }
			public Connection getConnection(String username, String password) throws SQLException {
				ClickHouseDataSource ds = new ClickHouseDataSource(this.getUrl());
				if (StringUtils.isEmpty(username) || StringUtils.isEmpty(password)) {
					return ds.getConnection();
				} else {
					return ds.getConnection(username, password);
				}
			}
		};
		druid.setDriver(new ClickHouseDriver());
		druid.setUrl(info.getUrl());
		druid.setUsername(info.getUsername());
		druid.setPassword(info.getPassword());
		druid.setMinIdle(info.getPool().getIdle());
		druid.setInitialSize(info.getPool().getIdle());
		druid.setMaxActive(info.getPool().getMax());
		
		druid.setTestWhileIdle(true);
		druid.setValidationQuery("select 1");
		return druid;
	}
	
}
